package com.easygoods.service;

import com.bestvike.linq.Linq;
import com.bestvike.stone.core.lang.Convert;
import com.bestvike.stone.core.lang.StringUtils;
import com.bestvike.stone.spring.exception.BusinessException;
import com.bestvike.stone.spring.exception.ErrorCode;
import com.bestvike.stone.spring.service.BaseService;
import com.easygoods.dao.SysConfigDao;
import com.easygoods.entity.SysConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

/**
 * Created by 许崇雷 on 2019-01-15.
 */
@Service
public class ConfigService extends BaseService {
    private static final char[] SPLIT = {','};
    private Integer[] gradeLowerArray;//等级积分下限
    private String[] gradeNameArray;//等级名称
    private BigDecimal[] priceRatioArray;//等级价格系数
    private BigDecimal returnRatio;//返利系数
    private BigDecimal firstBuyCouponAmount;//首次购买,邀请人获得代金券金额
    private Integer firstBuyCouponValidDays;//首次购买,邀请人获得代金券有效期
    private Integer pointKeepYears;//积分保存年份
    private Integer pointX;//积分公式
    private Integer pointPerHundred;//积分公式
    private Integer pointMax;//积分公式
    private Integer registerPoint;//注册赠送积分值
    private Integer firstBuyMinPoint;//首次购买最小积分值
    private Integer autoPointGrade;//自动获得积分等级
    private BigDecimal autoPointRate;//自动获得积分系数
    private String shareText;//多个商品分享文本


    @Autowired
    private SysConfigDao sysConfigDao;

    //计算精度
    public static MathContext getMathContext() {
        return MathContext.DECIMAL128;
    }

    //获取支付密码长度
    public static int getPayPwdLength() {
        return 6;
    }

    private SysConfig getConfig(String id) {
        SysConfig sysConfig = this.sysConfigDao.selectByPrimaryKey(id);
        if (sysConfig == null) {
            this.log.error("未配置:" + id);
            throw new BusinessException(ErrorCode.ERROR_SERVER, "无效操作");
        }
        if (sysConfig.getConfigValue() == null) {
            this.log.error("配置的值为 NULL:" + id);
            throw new BusinessException(ErrorCode.ERROR_SERVER, "无效操作");
        }
        return sysConfig;
    }

    private <T> T[] getArrayConfig(String id, Class<T> clazz) {
        SysConfig sysConfig = this.getConfig(id);
        String configValue = sysConfig.getConfigValue();
        String[] split = StringUtils.split(configValue, SPLIT, true);
        return Linq.asEnumerable(split).select(a -> Convert.toType(StringUtils.trim(a), clazz)).toArray(clazz);
    }

    private <T> T getValueConfig(String id, Class<T> clazz) {
        SysConfig sysConfig = this.getConfig(id);
        String configValue = sysConfig.getConfigValue();
        return Convert.toType(configValue, clazz);
    }

    //获取等级上限数组 N-1 个
    public Integer[] getGradeLowerArray() {
        if (this.gradeLowerArray == null)
            this.gradeLowerArray = this.getArrayConfig("grade_lower_array", Integer.class);
        return this.gradeLowerArray;
    }

    //获取等级名称 N 个
    public String[] getGradeNameArray() {
        if (this.gradeNameArray == null)
            return this.gradeNameArray = this.getArrayConfig("grade_name_array", String.class);
        return this.gradeNameArray;
    }

    //获取等级会员价系数 N 个
    public BigDecimal[] getPriceRatioArray() {
        if (this.priceRatioArray == null)
            return this.priceRatioArray = this.getArrayConfig("price_ratio_array", BigDecimal.class);
        return this.priceRatioArray;
    }

    //获取非首次返利比率,0-1
    public BigDecimal getReturnRatio() {
        if (this.returnRatio == null)
            return this.returnRatio = this.getValueConfig("return_ratio", BigDecimal.class);
        return this.returnRatio;
    }

    //获取首次购买赠送代金券金额
    public BigDecimal getFirstBuyCouponAmount() {
        if (this.firstBuyCouponAmount == null)
            return this.firstBuyCouponAmount = this.getValueConfig("first_buy_coupon_amount", BigDecimal.class);
        return this.firstBuyCouponAmount;
    }

    //获取首次购买赠送代金券有效天数
    public Integer getFirstBuyCouponValidDays() {
        if (this.firstBuyCouponValidDays == null)
            return this.firstBuyCouponValidDays = this.getValueConfig("first_buy_coupon_valid_days", Integer.class);
        return this.firstBuyCouponValidDays;
    }

    //获取积分保存年数
    public int getPointKeepYears() {
        if (this.pointKeepYears == null)
            return this.pointKeepYears = this.getValueConfig("point_keep_years", Integer.class);
        return this.pointKeepYears;
    }

    //价格舍入
    public BigDecimal roundPrice(BigDecimal price) {
        Assert.notNull(price, "price can not be null");
        return price.setScale(2, RoundingMode.HALF_UP);
    }

    //金额舍入
    public BigDecimal roundAmount(BigDecimal amount) {
        Assert.notNull(amount, "amount can not be null");
        return amount.setScale(2, RoundingMode.HALF_UP);
    }

    //奖励抹零
    public BigDecimal roundReward(BigDecimal cash) {
        Assert.notNull(cash, "cash can not be null");
        return cash.setScale(2, RoundingMode.HALF_DOWN);
    }

    //收益率舍入
    public BigDecimal roundEarnRate(BigDecimal earnRate) {
        Assert.notNull(earnRate, "earnRate can not be null");
        return earnRate.setScale(4, RoundingMode.HALF_UP);
    }

    //获取商品在X元以下，商品积分等于商品价格
    public Integer getPointX() {
        if (this.pointX == null)
            this.pointX = this.getValueConfig("point_x", Integer.class);
        return this.pointX;
    }

    //获取商品价格超过X元的部分,每增加100元，积分增加N个
    public Integer getPointPerHundred() {
        if (this.pointPerHundred == null)
            this.pointPerHundred = this.getValueConfig("point_per_hundred", Integer.class);
        return this.pointPerHundred;
    }

    //获取最大积分
    public Integer getPointMax() {
        if (this.pointMax == null)
            this.pointMax = this.getValueConfig("point_max", Integer.class);
        return this.pointMax;
    }

    //注册赠送积分值
    public Integer getRegisterPoint() {
        if (this.registerPoint == null)
            this.registerPoint = this.getValueConfig("register_point", Integer.class);
        return this.registerPoint;
    }

    //首次购买最小积分值
    public Integer getFirstBuyMinPoint() {
        if (this.firstBuyMinPoint == null)
            this.firstBuyMinPoint = this.getValueConfig("first_buy_min_point", Integer.class);
        return this.firstBuyMinPoint;
    }

    //自动获得积分等级
    public Integer getAutoPointGrade() {
        if (this.autoPointGrade == null)
            this.autoPointGrade = this.getValueConfig("auto_point_grade", Integer.class);
        return this.autoPointGrade;
    }

    //自动获得积分系数
    public BigDecimal getAutoPointRate() {
        if (this.autoPointRate == null)
            this.autoPointRate = this.getValueConfig("auto_point_rate", BigDecimal.class);
        return this.autoPointRate;
    }

    //多个商品分享文本
    public String getShareText() {
        if (this.shareText == null)
            this.shareText = this.getValueConfig("share_text", String.class);
        return this.shareText;
    }
}
